﻿using AutoMapper;
using HamcoWcs.Contract.ContractCommon;
using HamcoWcs.Contract.ContractMes;
using HamcoWcs.DAL;
using HamcoWcs.Entitys.PalletInfos;
using HamcoWcs.Models.Common;
using HamcoWcs.Models.Common.Enums;
using HamcoWcs.Models.Devices;
using HamcoWcs.Models.TibcoMessage;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HamcoWcs.Service.Pcon.PconPlcDbMsgParsers
{
    /// <summary>
    /// 码头验证货物信息
    /// </summary>
    public class PconMsgParse_Valid : PconMsgParseBase
    {
        public override EnumPconPlcRequest RequestType => EnumPconPlcRequest.Valid;
        private readonly ILoggerService _logger;
        private readonly IBaseConfigService _config;
        public PconMsgParse_Valid(ILoggerService logger, IMapper mapper, WcsDbContext wcsDbContext,
            IMesCommunicateService mesCommunicateService, IBaseConfigService config)
            : base(mesCommunicateService, wcsDbContext, mapper)
        {
            _logger = logger;
            _config = config;
        }

        private string GetPalletIdAndBoxId(PconDto pconDto, PconPlc pconPlc)
        {
            var db = pconPlc.DbInfo.FirstOrDefault(x => x.DbName == "other_recv");

            int offset;
            if (pconDto.MachineName == "CJRCV100")
            {
                offset = 186;
            }
            else if (pconDto.MachineName == "CJRCV200")
            {
                offset = 282;

            }
            else if (pconDto.MachineName == "CJRCV300")
            {
                offset = 378;

            }
            else if (pconDto.MachineName == "CJRCV400")
            {
                offset = 474;
            }
            else
            {
                return string.Empty;
            }

            var dbBuffer = db.Buffer.Skip(offset).Take(GlobalValue.VALID_READ_LENGTH).ToArray();
            var str = Encoding.ASCII.GetString(dbBuffer);

            return str;
        }

        public override void Deal(PconDto pconDto, PconPlc pconPlc)
        {
            var a1 = _config.TryGetConfigValue("WHARFFULLSTORETHRESHOLD", out string _threshold);
            if (!a1) _threshold = "95";
            var b1 = int.TryParse(_threshold, out int threshold);
            if (!b1) threshold = 95;
            if (threshold > 100) threshold = 100;

            var locs = _wcsDbContext.WcsLocations
                .AsNoTracking()
                .Where(x => x.LocType == "shelf")
                .ToList();

            string ailse = "";
            if (pconDto.MachineName == "CJRCV100" || pconDto.MachineName == "CJRCV200")
            {
                ailse = "CJSTW200";
            }
            if (pconDto.MachineName == "CJRCV300" || pconDto.MachineName == "CJRCV400")
            {
                ailse = "CJSTW100";
            }

            int allowEmptyCount = locs.Where(X => X.Aisle == ailse).Count() * (100 - threshold) / 100;
            int emptyCount = locs.Where(x => x.LocStatus == (int)EnumLocStatus.Empty)
                .Where(x => !x.IsLock && !x.SrmOccupyFlag)
                .Count();

            if (emptyCount < allowEmptyCount)
            {
                _logger.AddWcsRunLog(pconDto.UnitId, $"{pconDto.DeviceName}爆仓退回");
                RejectValid(pconDto, 13);
                return;
            }


            var str = GetPalletIdAndBoxId(pconDto, pconPlc);
            if (string.IsNullOrEmpty(str))
            {
                _logger.AddWcsRunLog(pconDto.UnitId, $"{pconDto.DeviceName}验证码头入库栈板信息，扫码信息未取得");
                RejectValid(pconDto, 1);
                return;
            }


            EnumPalletType type = (EnumPalletType)pconDto.CheckRes;

            var strs = str.Split('|', StringSplitOptions.RemoveEmptyEntries);
            var unitId = strs[0];

            if (unitId != pconDto.UnitId)
            {
                _logger.AddWcsRunLog(pconDto.UnitId, $"{pconDto.DeviceName}验证码头入库栈板信息，设备上报栈板号和扫码获取的不同");
                RejectValid(pconDto, 2);
                return;
            }

            var a = _wcsDbContext.WcsLocations
                .Where(x => x.LocType == "shelf")
                .Any(x => x.UnitId == unitId);
            if (a)
            {
                _logger.AddWcsRunLog(pconDto.UnitId, $"{pconDto.DeviceName}验证码头入库栈板信息，储位中已有相同栈板号");
                RejectValid(pconDto, 11);
                return;
            }

            try
            {
                var palletInfo = _wcsDbContext.Set<PalletInfo>().FirstOrDefault(x => x.UnitId == unitId);
                if (palletInfo != null)
                {

                    palletInfo.PalletType = type.ToString();
                    _wcsDbContext.SaveChanges();
                }
                else
                {
                    palletInfo = new PalletInfo()
                    {
                        UnitId = unitId,
                        PalletType = type.ToString()
                    };
                    _wcsDbContext.Set<PalletInfo>().Add(palletInfo);
                    _wcsDbContext.SaveChanges();
                }
            }
            catch (Exception)
            {

            }

            switch (type)
            {
                case EnumPalletType.FULL:
                    _mesCommunicateService.ValidatePalletInputRequest(new ValidatePalletInputMessage(
                        new ValidatePalletInputMessageBody(pconDto.MachineName, pconDto.PortName, pconDto.UnitId)));
                    break;
                case EnumPalletType.EMPTYBOX:
                    var boxes = new List<Box>();

                    for (int i = 1; i < strs.Length; i++)
                    {
                        boxes.Add(new Box()
                        {
                            BoxName = strs[i].Trim(),
                            Position = i.ToString()
                        });
                    }

                    _mesCommunicateService.PalletAndBoxAssignRequest(new PalletAndBoxAssignMessage(
                        new PalletAndBoxAssignMessageBody()
                        {
                            MachineName = pconDto.MachineName,
                            PortName = pconDto.PortName,
                            EventUser = pconDto.MachineName,
                            PalletName = pconDto.UnitId,
                            BoxQuantity = boxes.Count.ToString(),
                            BoxList = new BoxList(boxes)
                        }));
                    break;
                case EnumPalletType.PALLET:
                    var pallets = new List<Pallet>();
                    if (strs.Length > 1)
                    {
                        for (int i = 1; i < strs.Length; i++)
                        {
                            pallets.Add(new Pallet()
                            {
                                PalletName = strs[i].ToString(),
                                Position = i.ToString()
                            });
                        }
                    }

                    _mesCommunicateService.ValidatePalletListRequest(new ValidatePalletListMessage(
                        new ValidatePalletListMessageBody()
                        {
                            MachineName = pconDto.MachineName,
                            PortName = pconDto.PortName,
                            EventUser = pconDto.MachineName,
                            PalletName = pconDto.UnitId,
                            PalletQty = strs.Length.ToString(),
                            PalletList = new PalletList(pallets)
                        }));
                    break;
                case EnumPalletType.None:
                default:
                    _logger.AddWcsRunLog(pconDto.UnitId, $"{pconDto.DeviceName}验证码头入库栈板信息，栈板类型上报异常");
                    RejectValid(pconDto, 3);
                    break;
            }
        }
    }
}
